import {
  IsString,
  IsOptional,
  IsEnum,
  IsBoolean,
  IsDateString,
  MinLength,
  MaxLength,
  IsArray,
  ValidateNested,
  IsUUID,
  IsInt,
  Min,
  Max,
  IsUrl
} from 'class-validator'
import { Transform, Type } from 'class-transformer'
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'
import { PaginationDto } from './base.dto'
import { IsUrlWithChinese } from '../validators/custom.validators'

/**
 * 文章状态枚举
 */
export enum ArticleStatus {
  DRAFT = 'draft',
  PUBLISHED = 'published',
  ARCHIVED = 'archived',
  DELETED = 'deleted'
}

/**
 * 文章类型枚举
 */
export enum ArticleType {
  POST = 'post',
  PAGE = 'page',
  NEWS = 'news',
  TUTORIAL = 'tutorial',
  REVIEW = 'review'
}

/**
 * 创建文章DTO
 */
export class CreateArticleDto {
  @ApiProperty({ description: '文章标题', example: '如何使用NestJS构建CMS系统' })
  @IsString({ message: '文章标题必须是字符串' })
  @MinLength(1, { message: '文章标题不能为空' })
  @MaxLength(200, { message: '文章标题不能超过200个字符' })
  @Transform(({ value }) => value?.trim())
  title: string

  @ApiProperty({ description: '文章内容', example: '这是一篇关于NestJS的教程...' })
  @IsString({ message: '文章内容必须是字符串' })
  @MinLength(1, { message: '文章内容不能为空' })
  content: string

  @ApiPropertyOptional({ description: '文章摘要', example: '本文介绍了如何使用NestJS构建CMS系统' })
  @IsOptional()
  @IsString({ message: '文章摘要必须是字符串' })
  @MaxLength(500, { message: '文章摘要不能超过500个字符' })
  @Transform(({ value }) => value?.trim())
  excerpt?: string

  @ApiPropertyOptional({
    description: '文章别名（URL友好）',
    example: 'how-to-build-cms-with-nestjs'
  })
  @IsOptional()
  @IsString({ message: '文章别名必须是字符串' })
  @MaxLength(200, { message: '文章别名不能超过200个字符' })
  @Transform(({ value }) =>
    value
      ?.trim()
      .toLowerCase()
      .replace(/[^a-z0-9-]/g, '-')
  )
  slug?: string

  @ApiPropertyOptional({ description: '特色图片URL', example: 'https://example.com/featured.jpg' })
  @IsOptional()
  @IsUrlWithChinese({ message: '特色图片URL格式不正确' })
  featuredImage?: string

  @ApiPropertyOptional({ description: '文章类型', enum: ArticleType, example: ArticleType.POST })
  @IsOptional()
  @IsEnum(ArticleType, { message: '文章类型不正确' })
  type?: ArticleType = ArticleType.POST

  @ApiPropertyOptional({
    description: '文章状态',
    enum: ArticleStatus,
    example: ArticleStatus.DRAFT
  })
  @IsOptional()
  @IsEnum(ArticleStatus, { message: '文章状态不正确' })
  status?: ArticleStatus = ArticleStatus.DRAFT

  @ApiPropertyOptional({ description: '分类ID', example: 'uuid-123' })
  @IsOptional()
  @IsUUID('4', { message: '分类ID格式不正确' })
  categoryId?: string

  @ApiPropertyOptional({ description: '标签列表', example: ['NestJS', 'CMS', 'TypeScript'] })
  @IsOptional()
  @IsArray({ message: '标签列表必须是数组' })
  @IsString({ each: true, message: '标签必须是字符串' })
  @MaxLength(50, { each: true, message: '标签长度不能超过50个字符' })
  @Transform(({ value }) => value?.map((tag: string) => tag.trim()).filter(Boolean))
  tags?: string[]

  @ApiPropertyOptional({ description: '是否允许评论', example: true })
  @IsOptional()
  @IsBoolean({ message: '是否允许评论必须是布尔值' })
  @Transform(({ value }) => value === 'true' || value === true)
  allowComments?: boolean = true

  @ApiPropertyOptional({ description: '是否置顶', example: false })
  @IsOptional()
  @IsBoolean({ message: '是否置顶必须是布尔值' })
  @Transform(({ value }) => value === 'true' || value === true)
  isSticky?: boolean = false

  @ApiPropertyOptional({ description: '发布时间', example: '2024-01-01T00:00:00.000Z' })
  @IsOptional()
  @IsDateString({}, { message: '发布时间格式不正确' })
  publishedAt?: string

  @ApiPropertyOptional({ description: 'SEO标题', example: 'NestJS CMS系统构建指南' })
  @IsOptional()
  @IsString({ message: 'SEO标题必须是字符串' })
  @MaxLength(200, { message: 'SEO标题不能超过200个字符' })
  @Transform(({ value }) => value?.trim())
  seoTitle?: string

  @ApiPropertyOptional({
    description: 'SEO描述',
    example: '详细介绍如何使用NestJS构建现代化CMS系统'
  })
  @IsOptional()
  @IsString({ message: 'SEO描述必须是字符串' })
  @MaxLength(500, { message: 'SEO描述不能超过500个字符' })
  @Transform(({ value }) => value?.trim())
  seoDescription?: string

  @ApiPropertyOptional({
    description: 'SEO关键词',
    example: ['NestJS', 'CMS', 'TypeScript', 'Node.js']
  })
  @IsOptional()
  @IsArray({ message: 'SEO关键词必须是数组' })
  @IsString({ each: true, message: 'SEO关键词必须是字符串' })
  @MaxLength(50, { each: true, message: 'SEO关键词长度不能超过50个字符' })
  seoKeywords?: string[]
}

/**
 * 更新文章DTO
 */
export class UpdateArticleDto {
  @ApiPropertyOptional({ description: '文章标题', example: '如何使用NestJS构建CMS系统' })
  @IsOptional()
  @IsString({ message: '文章标题必须是字符串' })
  @MinLength(1, { message: '文章标题不能为空' })
  @MaxLength(200, { message: '文章标题不能超过200个字符' })
  @Transform(({ value }) => value?.trim())
  title?: string

  @ApiPropertyOptional({ description: '文章内容', example: '这是一篇关于NestJS的教程...' })
  @IsOptional()
  @IsString({ message: '文章内容必须是字符串' })
  @MinLength(1, { message: '文章内容不能为空' })
  content?: string

  @ApiPropertyOptional({ description: '文章摘要', example: '本文介绍了如何使用NestJS构建CMS系统' })
  @IsOptional()
  @IsString({ message: '文章摘要必须是字符串' })
  @MaxLength(500, { message: '文章摘要不能超过500个字符' })
  @Transform(({ value }) => value?.trim())
  excerpt?: string

  @ApiPropertyOptional({
    description: '文章别名（URL友好）',
    example: 'how-to-build-cms-with-nestjs'
  })
  @IsOptional()
  @IsString({ message: '文章别名必须是字符串' })
  @MaxLength(200, { message: '文章别名不能超过200个字符' })
  @Transform(({ value }) =>
    value
      ?.trim()
      .toLowerCase()
      .replace(/[^a-z0-9-]/g, '-')
  )
  slug?: string

  @ApiPropertyOptional({ description: '特色图片URL', example: 'https://example.com/featured.jpg' })
  @IsOptional()
  @IsUrlWithChinese({ message: '特色图片URL格式不正确' })
  featuredImage?: string

  @ApiPropertyOptional({ description: '文章类型', enum: ArticleType, example: ArticleType.POST })
  @IsOptional()
  @IsEnum(ArticleType, { message: '文章类型不正确' })
  type?: ArticleType

  @ApiPropertyOptional({
    description: '文章状态',
    enum: ArticleStatus,
    example: ArticleStatus.PUBLISHED
  })
  @IsOptional()
  @IsEnum(ArticleStatus, { message: '文章状态不正确' })
  status?: ArticleStatus

  @ApiPropertyOptional({ description: '分类ID', example: 'uuid-123' })
  @IsOptional()
  @IsUUID('4', { message: '分类ID格式不正确' })
  categoryId?: string

  @ApiPropertyOptional({ description: '标签列表', example: ['NestJS', 'CMS', 'TypeScript'] })
  @IsOptional()
  @IsArray({ message: '标签列表必须是数组' })
  @IsString({ each: true, message: '标签必须是字符串' })
  @MaxLength(50, { each: true, message: '标签长度不能超过50个字符' })
  @Transform(({ value }) => value?.map((tag: string) => tag.trim()).filter(Boolean))
  tags?: string[]

  @ApiPropertyOptional({ description: '是否允许评论', example: true })
  @IsOptional()
  @IsBoolean({ message: '是否允许评论必须是布尔值' })
  @Transform(({ value }) => value === 'true' || value === true)
  allowComments?: boolean

  @ApiPropertyOptional({ description: '是否置顶', example: false })
  @IsOptional()
  @IsBoolean({ message: '是否置顶必须是布尔值' })
  @Transform(({ value }) => value === 'true' || value === true)
  isSticky?: boolean

  @ApiPropertyOptional({ description: '发布时间', example: '2024-01-01T00:00:00.000Z' })
  @IsOptional()
  @IsDateString({}, { message: '发布时间格式不正确' })
  publishedAt?: string

  @ApiPropertyOptional({ description: 'SEO标题', example: 'NestJS CMS系统构建指南' })
  @IsOptional()
  @IsString({ message: 'SEO标题必须是字符串' })
  @MaxLength(200, { message: 'SEO标题不能超过200个字符' })
  @Transform(({ value }) => value?.trim())
  seoTitle?: string

  @ApiPropertyOptional({
    description: 'SEO描述',
    example: '详细介绍如何使用NestJS构建现代化CMS系统'
  })
  @IsOptional()
  @IsString({ message: 'SEO描述必须是字符串' })
  @MaxLength(500, { message: 'SEO描述不能超过500个字符' })
  @Transform(({ value }) => value?.trim())
  seoDescription?: string

  @ApiPropertyOptional({
    description: 'SEO关键词',
    example: ['NestJS', 'CMS', 'TypeScript', 'Node.js']
  })
  @IsOptional()
  @IsArray({ message: 'SEO关键词必须是数组' })
  @IsString({ each: true, message: 'SEO关键词必须是字符串' })
  @MaxLength(50, { each: true, message: 'SEO关键词长度不能超过50个字符' })
  seoKeywords?: string[]
}

/**
 * 文章查询DTO
 */
export class QueryArticleDto extends PaginationDto {
  @ApiPropertyOptional({ description: '搜索关键词（标题、内容、摘要）', example: 'NestJS' })
  @IsOptional()
  @IsString({ message: '搜索关键词必须是字符串' })
  @MaxLength(100, { message: '搜索关键词不能超过100个字符' })
  @Transform(({ value }) => value?.trim())
  search?: string = ''

  @ApiPropertyOptional({
    description: '文章状态',
    enum: ArticleStatus,
    example: ArticleStatus.PUBLISHED
  })
  @IsOptional()
  @IsEnum(ArticleStatus, { message: '文章状态不正确' })
  status?: ArticleStatus

  @ApiPropertyOptional({ description: '文章类型', enum: ArticleType, example: ArticleType.POST })
  @IsOptional()
  @IsEnum(ArticleType, { message: '文章类型不正确' })
  type?: ArticleType

  @ApiPropertyOptional({ description: '分类ID', example: 'uuid-123' })
  @IsOptional()
  @IsUUID('4', { message: '分类ID格式不正确' })
  categoryId?: string

  @ApiPropertyOptional({ description: '作者ID', example: 'uuid-456' })
  @IsOptional()
  @IsUUID('4', { message: '作者ID格式不正确' })
  authorId?: string

  @ApiPropertyOptional({ description: '标签', example: 'NestJS' })
  @IsOptional()
  @IsString({ message: '标签必须是字符串' })
  @MaxLength(50, { message: '标签长度不能超过50个字符' })
  tag?: string

  @ApiPropertyOptional({ description: '是否置顶', example: true })
  @IsOptional()
  @IsBoolean({ message: '是否置顶必须是布尔值' })
  @Transform(({ value }) => {
    if (value === 'true') return true
    if (value === 'false') return false
    return value
  })
  isSticky?: boolean

  @ApiPropertyOptional({ description: '发布开始日期', example: '2024-01-01' })
  @IsOptional()
  @IsDateString({}, { message: '发布开始日期格式不正确' })
  publishedFrom?: string

  @ApiPropertyOptional({ description: '发布结束日期', example: '2024-12-31' })
  @IsOptional()
  @IsDateString({}, { message: '发布结束日期格式不正确' })
  publishedTo?: string

  @ApiPropertyOptional({ description: '创建开始日期', example: '2024-01-01' })
  @IsOptional()
  @IsDateString({}, { message: '创建开始日期格式不正确' })
  createdFrom?: string

  @ApiPropertyOptional({ description: '创建结束日期', example: '2024-12-31' })
  @IsOptional()
  @IsDateString({}, { message: '创建结束日期格式不正确' })
  createdTo?: string
}

/**
 * 文章响应DTO
 */
export class ArticleResponseDto {
  @ApiProperty({ description: '文章ID', example: 'uuid-123' })
  id: string

  @ApiProperty({ description: '文章标题', example: '如何使用NestJS构建CMS系统' })
  title: string

  @ApiProperty({ description: '文章内容', example: '这是一篇关于NestJS的教程...' })
  content: string

  @ApiPropertyOptional({ description: '文章摘要', example: '本文介绍了如何使用NestJS构建CMS系统' })
  excerpt?: string

  @ApiProperty({ description: '文章别名', example: 'how-to-build-cms-with-nestjs' })
  slug: string

  @ApiPropertyOptional({ description: '特色图片URL', example: 'https://example.com/featured.jpg' })
  featuredImage?: string

  @ApiProperty({ description: '文章类型', enum: ArticleType, example: ArticleType.POST })
  type: ArticleType

  @ApiProperty({ description: '文章状态', enum: ArticleStatus, example: ArticleStatus.PUBLISHED })
  status: ArticleStatus

  @ApiProperty({ description: '作者信息' })
  author: {
    id: string
    username: string
    realName?: string
    avatar?: string
  }

  @ApiPropertyOptional({ description: '分类信息' })
  category?: {
    id: string
    name: string
    slug: string
  }

  @ApiProperty({ description: '标签列表', example: ['NestJS', 'CMS', 'TypeScript'] })
  tags: string[]

  @ApiProperty({ description: '是否允许评论', example: true })
  allowComments: boolean

  @ApiProperty({ description: '是否置顶', example: false })
  isSticky: boolean

  @ApiProperty({ description: '浏览次数', example: 1000 })
  viewCount: number

  @ApiProperty({ description: '点赞次数', example: 50 })
  likeCount: number

  @ApiProperty({ description: '评论次数', example: 20 })
  commentCount: number

  @ApiPropertyOptional({ description: '发布时间', example: '2024-01-01T00:00:00.000Z' })
  publishedAt?: Date

  @ApiProperty({ description: '创建时间', example: '2024-01-01T00:00:00.000Z' })
  createdAt: Date

  @ApiProperty({ description: '更新时间', example: '2024-01-01T00:00:00.000Z' })
  updatedAt: Date

  @ApiPropertyOptional({ description: 'SEO标题', example: 'NestJS CMS系统构建指南' })
  seoTitle?: string

  @ApiPropertyOptional({
    description: 'SEO描述',
    example: '详细介绍如何使用NestJS构建现代化CMS系统'
  })
  seoDescription?: string

  @ApiPropertyOptional({
    description: 'SEO关键词',
    example: ['NestJS', 'CMS', 'TypeScript', 'Node.js']
  })
  seoKeywords?: string[]
}

/**
 * 文章统计DTO
 */
export class ArticleStatsDto {
  @ApiProperty({ description: '总文章数', example: 500 })
  total: number

  @ApiProperty({ description: '已发布文章数', example: 400 })
  published: number

  @ApiProperty({ description: '草稿文章数', example: 80 })
  draft: number

  @ApiProperty({ description: '今日新增文章数', example: 5 })
  todayNew: number

  @ApiProperty({ description: '本月新增文章数', example: 50 })
  monthNew: number

  @ApiProperty({ description: '各状态文章数统计' })
  statusStats: Record<ArticleStatus, number>

  @ApiProperty({ description: '各类型文章数统计' })
  typeStats: Record<ArticleType, number>

  @ApiProperty({ description: '热门文章（按浏览量）' })
  popularArticles: Array<{
    id: string
    title: string
    viewCount: number
  }>

  @ApiProperty({ description: '最新文章' })
  recentArticles: Array<{
    id: string
    title: string
    createdAt: Date
  }>
}

/**
 * 批量操作文章DTO
 */
export class BulkArticleOperationDto {
  @ApiProperty({ description: '文章ID列表', example: ['uuid-1', 'uuid-2'] })
  @IsArray({ message: '文章ID列表必须是数组' })
  @IsUUID('4', { each: true, message: '文章ID格式不正确' })
  articleIds: string[]

  @ApiProperty({ description: '操作类型', enum: ['publish', 'unpublish', 'archive', 'delete'] })
  @IsEnum(['publish', 'unpublish', 'archive', 'delete'], { message: '操作类型不正确' })
  operation: 'publish' | 'unpublish' | 'archive' | 'delete'

  @ApiPropertyOptional({ description: '操作原因', example: '批量发布文章' })
  @IsOptional()
  @IsString({ message: '操作原因必须是字符串' })
  @MaxLength(500, { message: '操作原因不能超过500个字符' })
  reason?: string
}
